<?php

/**
 * This is the model class for table "video".
 *
 * The followings are the available columns in table 'video':
 * @property string $id
 * @property string $name
 * @property integer $time_create
 * @property integer $time_update
 * @property string $url
 * @property integer $plays
 * @property integer $time
 * @property string $label
 * @property string $avetar
 * @property string $status
 * @property string $source_url
 * @property integer $task_id
 */
class Video extends CActiveRecord
{
    use util_array;
    const STATUS_INIT = 'init';
    const STATUS_WAITING = 'waiting';
    const STATUS_DOWNLOADING = 'downloading';
    const STATUS_COMPLETE = 'complete';
    const STATUS_FAILED = 'failed';


    public $time_begin;
    public $time_end;
    public $searchKey;


    private static $_options;

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'video';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
        return array(
            array('time_create, time_update, plays, time, task_id', 'numerical', 'integerOnly' => true),
            array('label,', 'length', 'max' => 11),
            array('source_url,', 'unique'),
            array('name,avetar,url,avetar,source_url', 'length', 'max' => 128),
// The following rule is used by search().
// @todo Please remove those attributes that should not be searched.
            array('id, name, time_create, time_update, url, plays, time, label, avetar, status, source_url, task_id', 'safe', 'on' => 'search'),
            array('time_begin, time_end,searchKey', 'safe', 'on' => 'search'),
            array(
                'time_update',
                'default',
                'value' => time(),
                'setOnEmpty' => false,
                'on' => 'update'
            ),
            array(
                'time_create, time_update',
                'default',
                'value' => time(),
                'on' => 'insert'
            ),
            array(
                'status',
                'default',
                'value' => self::STATUS_WAITING,
                'on' => 'insert'
            ),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
        return array(
            'task' => array(self::HAS_ONE, 'Task', ['id' => 'task_id']),
        );
    }


    public function findTopics()
    {
        $sql = '';
        $params = [];
        $sql .= 'select t.* ';
        $sql .= 'from topic t,video v ,task ta, topic_ext e';
        $sql .= ' where v.`id` =:id and 
        v.`task_id` = ta.`id` and e.`tid`=t.`id` and
         ((e.`ext_id` = v.`id` and e.`type`=:videoType ) or (e.`ext_id`=ta.`id` and e.`type`=:taskType))';
        $params[':id'] = $this->id;
        $params[':videoType'] = TopicExt::TYPE_VIDEO;
        $params[':taskType'] = TopicExt::TYPE_TASK;

        return Topic::model()->findAllBySql($sql, $params);
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'name' => 'Name',
            'time_create' => 'Time Create',
            'time_update' => 'Time Update',
            'url' => 'Url',
            'plays' => 'Plays',
            'time' => 'Time',
            'label' => 'Label',
            'avetar' => 'Avetar',
            'status' => 'Status',
            'source_url' => 'Source Url',
            'task_id' => 'Task',
            'time_begin' => 'time Begin',
            'time_end' => 'time_End',
            'searchKey' => 'searchKey',

        );
    }

    public static function getOptions($attribute, $options = array())
    {
        if (!isset(self::$_options[$attribute])) {
            $opts = [];
            switch ($attribute) {
                case 'videos':
                    $videos = self::model()->findAll();
                    foreach ($videos as $video) {
                        $opts[$video->id] = $video->name;
                    }
                    break;
                case 'status':
                    $opts[self::STATUS_WAITING] = '等待采集';
                    $opts[self::STATUS_DOWNLOADING] = '采集中';
                    $opts[self::STATUS_FAILED] = '采集失败';
                    $opts[self::STATUS_COMPLETE] = '采集完成';
                    break;
            }
            self::$_options[$attribute] = $opts;
        }
        if (is_array($options) && !empty($options)) {
            foreach (self::$_options[$attribute] as $k => $v) {
                $options[$k] = $v;
            }
        } else {
            $options = self::$_options[$attribute];
        }
        return $options;
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
// @todo Please modify the following code to remove attributes that should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id, true);
        $criteria->compare('name', $this->name, true);
        $criteria->compare('time_create', $this->time_create);
        $criteria->compare('time_update', $this->time_update);
        $criteria->compare('url', $this->url);
        $criteria->compare('plays', $this->plays);
        $criteria->compare('time', $this->time);
        $criteria->compare('label', $this->label, true);
        $criteria->compare('avetar', $this->avetar, true);
        $criteria->compare('status', $this->status);
        $criteria->compare('source_url', $this->source_url, true);
        $criteria->compare('task_id', $this->task_id);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    public function searchByKey()
    {
        $criteria = new CDbCriteria;
        if (isset($_GET['Video_sort'])) {
            $criteria->order = str_replace('.', ' ', $_GET['Video_sort']);
        } else {
            $criteria->order = 'time_create desc';
        }

        if ($this->searchKey !== '') {
            $criteria->compare('name', $this->searchKey, true);
        }

        if ($this->task_id !== '') {
            $criteria->compare('task_id', $this->task_id, false);
        }
        if ($this->status !== '') {
            $criteria->compare('status', $this->status, false);
        }
        if (!empty($ts_begin = strtotime($this->time_begin))) {
            $criteria->addCondition('`time_create` >= ' . $ts_begin);
        }
        if (!empty($ts_end = strtotime($this->time_end))) {
            $criteria->addCondition('`time_create` <= ' . $ts_end);
        }

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'pagination' => array(
                'pageSize' => 5,
            ),
        ));
    }

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return Video the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public function getSources()
    {
        $source = $this->url;
        return ['bq' => $source, 'gq' => $source, 'cq' => $source,];
    }

    public static function build($attrs, $task_id = null)
    {
        $model = new self();
        $model->setAttributes($attrs);
        $model->task_id = $task_id ? $task_id : null;
        return $model->validate()?$model:false;
    }


    /**
     * @param YoutubeDlCommand $dl
     */
    public function downLoad($dl)
    {
        $error = 0;
        $msg = '';
        $this->status = self::STATUS_DOWNLOADING;
        if (!$this->save()) {
            $error = 1;
            $msg = json_encode($this->getErrors());
        } else {
            list($error, $msg, $data) = $dl->downLoadVideo($this);
            if ($error) {
                Yii::log($msg, CLogger::LEVEL_ERROR, __METHOD__);
                $this->status = self::STATUS_FAILED;
                $this->save();
            } else {
                $values['url'] = Yii::app()->createAbsoluteUrl(self::util_array_get($data, 'url', null));
                $values['avetar'] = Yii::app()->createAbsoluteUrl(self::util_array_get($data, 'avetar', null));
                $this->setAttributes($values);
                if (!$this->save()) {
                    Yii::log(json_encode($this->getErrors()), CLogger::LEVEL_ERROR, __METHOD__);
                    $this->status = self::STATUS_FAILED;
                    $this->save();

                }
                $this->status = self::STATUS_COMPLETE;
                $this->save();
            }


        }
        return [$error, $msg,];
    }

}
